# 33. 符号运算
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
class Fraction {
constructor(fenzi, fenmu) {
if (fenmu === 0) {
throw new Error('ERROR');
}
let gcd = this.gcd(Math.abs(fenzi), Math.abs(fenmu));
this.fenzi = fenzi/gcd;
this.fenmu = fenmu/gcd;
if (this.fenmu < 0) {
this.fenzi = -this.fenzi;
this.fenmu = -this.fenmu;
}
}
add(other) {
return new Fraction(this.fenzi*other.fenmu+other.fenzi*this.fenmu, this.fenmu*other.fenmu);
}
subtract(other) {
return new Fraction(this.fenzi*other.fenmu-other.fenzi*this.fenmu, this.fenmu*other.fenmu);
}
multiply(other) {
return new Fraction(this.fenzi*other.fenzi, this.fenmu*other.fenmu);
}
divide(other) {
return new Fraction(this.fenzi*other.fenmu, this.fenmu*other.fenzi);
}
}
gcd(a,b) {
return b===0 ? a : this.gcd(b, a%b)
}
toString() {
if(this.fenzi === 1) {
return String(this.fenzi);
} else {
return this.fenzi + '/' + this.fenmu;
}
}
function calc(expression) {
let numbers = [];
let op = [];
for(let i=0; i<expression.length; i++) {
let c = expression[i];
if(!isNaN(c)) {
let j=i;
while(j<expression.length && !isNaN(expression[j])) {
j++;
}
let number = new Fraction(parseInt(expresssion.substring(i,j)), 1);
numbers.push(number);
i=j-1;
} else if(c==='(') {
op.push(c);
} else if(c===')') {
while(op[op-1] !== '(') {
preformCalc(numbers, op);
}
op.pop();
} else if(c=='+' || c=='-' || c=='*' || c=='/') {
while(op.length>0 && precedence(c) <= precedence(op[op.length-1]) ) {
preformCalc(numbers, op);
}
op.push(c);
}
}
while(op.length > 0) {
preformCalc(numbers, op);
}
return numbers.pop();
}
function performCalc(numbers, op) {
let b = numbers.pop();
let a = numbers.pop();
let opx = op.pop();
switch(opx) {
case '+':
numbers.push(a.add(b));
break;
case '-':
numbers.push(a.subtract(b));
break;
case '*':
numbers.push(a.multiply(b));
break;
case '/':
numbers.push(a.divide(b));
break;
}
}
function precedence(op) {
switch(op) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}
rl.on('line', (line) => {
try {
let res = calc(line);
console.log(res.toString());
} catch(e) {
console.log('ERROR');
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
← 32. 电脑病毒感染 34. 结对编程 →